package com.exception.global.config;

import ch.qos.logback.core.encoder.EchoEncoder;
import com.exception.global.exception.CustomException;
import com.exception.global.vo.ExceptionResponseVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 定义全局处理自定义异常的响应
     * @param request
     * @param e
     * @param response
     * @return
     */
    @ExceptionHandler(CustomException.class)
    public ExceptionResponseVO customExceptionHandler(HttpServletRequest request,
                                                     final Exception e, HttpServletResponse response) {
        response.setStatus(HttpStatus.BAD_REQUEST.value());
        CustomException customException = (CustomException) e;
        return new ExceptionResponseVO(customException.getCode(), customException.getMessage());
    }

    /**
     * 处理RuntimeException异常和响应
     * @param request
     * @param response
     * @param e
     * @return
     */
    @ExceptionHandler(RuntimeException.class)
    public ExceptionResponseVO runtimeExceptionHandler(HttpServletRequest request, HttpServletResponse response,
                                                       final Exception e) {
        response.setStatus(HttpStatus.BAD_REQUEST.value());
        RuntimeException runtimeException = (RuntimeException) e;
        return new ExceptionResponseVO("400", runtimeException.getMessage());
    }

    @Override
    protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {

        if (ex instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException exception = (MethodArgumentNotValidException) ex;
            return new ResponseEntity<>(new ExceptionResponseVO(status.value()+"", exception.getBindingResult().getAllErrors().get(0).getDefaultMessage()), status);
        }

        if (ex instanceof MethodArgumentTypeMismatchException) {
            MethodArgumentTypeMismatchException exception = (MethodArgumentTypeMismatchException) ex;
            log.error("参数转换失败，方法：{}，参数{}，信息：{}", exception.getParameter().getMethod().getName(),
                    exception.getName(), exception.getLocalizedMessage());
            return new ResponseEntity<>(new ExceptionResponseVO(status.value()+"", "参数转换失败"), status);
        }

        return new ResponseEntity<>(new ExceptionResponseVO(status.value()+"", "参数转换失败"), status);
    }
}
